<!DOCTYPE html>
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
  <meta name="description" content="along&#39;s blog">
  <meta name="keyword" content="hexo-theme, vuejs">
  
    <link rel="shortcut icon" href="/css/images/logo.png">
  
  <title>
    
      webpack | ALONG
    
  </title>
  <link href="/cdn.along/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <link href="/cdn.along/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
  <link href="/cdn.along/highlight.js/9.12.0/styles/tomorrow.min.css" rel="stylesheet">
  
<link rel="stylesheet" href="/css/style.css">

  
  <script src="/cdn.along/jquery/3.2.1/jquery.min.js"></script>
  <script src="/cdn.along/geopattern/1.2.3/js/geopattern.min.js"></script>
  <script src="/cdn.along/nprogress/0.2.0/nprogress.min.js"></script>
  
    
<script src="/js/qrious.js"></script>

  
  
  
  
    <!-- MathJax support START -->
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script type="text/javascript" src="/cdn.along/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <!-- MathJax support END -->
  


  
  
    
<script src="/js/local-search.js"></script>


<meta name="generator" content="Hexo 5.4.0"></head>
<div class="wechat-share">
  <img src="/css/images/logo.png" />
</div>
  <body>
    <header class="header fixed-header">
  <div class="header-container">
    <a class="home-link" href="/">
      <div class="logo"></div>
      <span>ALONG</span>
    </a>
    <ul class="right-list">
      
        <li class="list-item">
          
            <a href="/" class="item-link">Home</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/tags/" class="item-link">Tags</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/archives/" class="item-link">Archives</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/about/" class="item-link">About</a>
          
        </li>
      
      
        <li class="menu-item menu-item-search right-list">
    <a role="button" class="popup-trigger">
        <i class="fa fa-search fa-fw"></i>
    </a>
</li>
      
    </ul>
    <div class="menu">
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </div>
    <div class="menu-mask">
      <ul class="menu-list">
        
          <li class="menu-item">
            
              <a href="/" class="menu-link">Home</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/tags/" class="menu-link">Tags</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/archives/" class="menu-link">Archives</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/about/" class="menu-link">About</a>
            
          </li>
        
      </ul>
    </div>
    
      <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
            <span class="search-icon">
                <i class="fa fa-search"></i>
            </span>
            <div class="search-input-container">
                <input autocomplete="off" autocapitalize="off"
                    placeholder="Please enter your keyword(s) to search." spellcheck="false"
                    type="search" class="search-input">
            </div>
            <span class="popup-btn-close">
                <i class="fa fa-times-circle"></i>
            </span>
        </div>
        <div id="search-result">
            <div id="no-result">
                <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
            </div>
        </div>
    </div>
</div>
    
  </div>
</header>

    <div id="article-banner">
  <h2>webpack</h2>
  <p class="post-date">2020-08-27</p>
  <div class="arrow-down">
    <a href="javascript:;"></a>
  </div>
</div>
<main class="app-body flex-box">
  <!-- Article START -->
  <article class="post-article">
    <section class="markdown-content"><h2 id="WEBPACK"><a href="#WEBPACK" class="headerlink" title="WEBPACK"></a>WEBPACK</h2><h3 id="模块化问题"><a href="#模块化问题" class="headerlink" title="模块化问题"></a>模块化问题</h3><ul>
<li>兼容问题：  ES6 =&gt; ES5</li>
<li>模块文件多，网络请求频繁：  打包多个模块到一起</li>
<li>所有的前端资源都需要模块化：  打包不同类型文件</li>
</ul>
<h3 id="打包工具"><a href="#打包工具" class="headerlink" title="打包工具"></a>打包工具</h3><ul>
<li>webpack <ul>
<li>模块打包 Module bundler</li>
<li>模块加载 loader</li>
<li>代码拆分 Code Splitting</li>
<li>资源模块 Asset Module</li>
</ul>
</li>
</ul>
<h4 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yarn add webpack webpack-cli --dev</span><br></pre></td></tr></table></figure>

<h4 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h4><p>webpack 4 支持零配置打包，可以通过index.html中引入的script找到所有相关文件并打包</p>
<p>也可以通过修改配置自定义</p>
<p>创建 webpack.config.js 文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">const path &#x3D; require(&#39;path&#39;);</span><br><span class="line"></span><br><span class="line">module.exports &#x3D; &#123;</span><br><span class="line">    mode: &#39;none&#39;,</span><br><span class="line">    entry: &#39;.&#x2F;src&#x2F;index.js&#39;, &#x2F;&#x2F; 相对路径不能省略 .&#x2F;</span><br><span class="line">    output: &#123;</span><br><span class="line">        filename: &#39;bundle.js&#39;,</span><br><span class="line">        path: path.join(__dirname, &#39;output&#39;), &#x2F;&#x2F; 指定输出文件路径，必须是一个绝对路径</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="webpack-原理"><a href="#webpack-原理" class="headerlink" title="webpack 原理"></a>webpack 原理</h4><h4 id="webpack-资源加载-Loader"><a href="#webpack-资源加载-Loader" class="headerlink" title="webpack 资源加载 Loader"></a>webpack 资源加载 Loader</h4><p>webpack 加载资源的方式</p>
<ul>
<li><p>遵循ES Modules 标准的import声明</p>
</li>
<li><p>遵循CommonJS标准的require函数</p>
</li>
<li><p>遵循AMD标准的define函数和require函数</p>
</li>
<li><p>样式代码中的@import指令和url函数</p>
</li>
<li><p>HTML代码中图片标签的src属性</p>
</li>
</ul>
<p>loader 加载器类型大致分为三类</p>
<ul>
<li>编译转换类</li>
<li>文件操作类型  比如文件拷贝</li>
<li>代码检查类   eslint</li>
</ul>
<p>每一种资源都需要特定的加载器来加载。</p>
<p>通过webpack 配置文件中的 module.rules 来配置</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">module: &#123;</span><br><span class="line">    rules: [</span><br><span class="line">        &#123;test: &#x2F;.css$&#x2F;, use: &#39;css-loader&#39;&#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="处理css"><a href="#处理css" class="headerlink" title="处理css"></a>处理css</h5><p><code>[&#39;style-loader&#39;,&#39;css-loader&#39;]</code></p>
<h5 id="文件资源加载-图片字体"><a href="#文件资源加载-图片字体" class="headerlink" title="文件资源加载, 图片字体"></a>文件资源加载, 图片字体</h5><p><code>[&#39;file-loader&#39;]</code> file-loader 会在打包时将目标复制到输出文件夹，并将输出模块的路径作为返回值返回</p>
<p><code>[&#39;url-loader&#39;]</code> url-loader 采用Data urls 协议，（url直接表示文件内容），将文件转换成base64 直接写到代码中</p>
<p>最好的方式是较小的资源使用url-loader 转换，较大的文件使用file-loader 拷贝</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"> &#123;</span><br><span class="line">    test: &#x2F;\.(png|jpg|jpeg|gif)$&#x2F;,</span><br><span class="line">    use: &#123;</span><br><span class="line">        loader: &#39;url-loader&#39;,</span><br><span class="line">        options: &#123;</span><br><span class="line">            esModule: false,</span><br><span class="line">            limit: 10 * 1024,</span><br><span class="line">            &#x2F;&#x2F; outputPath: &#39;images&#x2F;&#39;,</span><br><span class="line">            &#x2F;&#x2F; name: &#39;[name].[hash:5].[ext]&#39;,</span><br><span class="line">            &#x2F;&#x2F; publicPath: &#39;&#39;, &#x2F;&#x2F; 可以写cdn地址</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="编译-ES6"><a href="#编译-ES6" class="headerlink" title="编译 ES6"></a>编译 ES6</h5><p><code>yarn add babel-loader @babel/core @babel/preset-env --dev</code></p>
<p>配置 规则</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">rules: [</span><br><span class="line">    &#123;</span><br><span class="line">        test: &#x2F;\.js$&#x2F;,</span><br><span class="line">        use: &#123;</span><br><span class="line">            loader: &#39;babel-loader&#39;,</span><br><span class="line">            options: &#123;</span><br><span class="line">                presets: [&#39;@babel&#x2F;preset-env&#39;]</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;&#39;,</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<h4 id="自定义-loader"><a href="#自定义-loader" class="headerlink" title="自定义 loader"></a>自定义 loader</h4><p>实现一个md转html的loader</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> marked = <span class="built_in">require</span>(<span class="string">&#x27;marked&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 参数 source 就是读取到的文件文本</span></span><br><span class="line"><span class="built_in">module</span>.exports = <span class="function"><span class="params">source</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> html = marked(source);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// loader管道的最后一个loader必须要分会一段js脚本文本</span></span><br><span class="line">    <span class="keyword">return</span> <span class="string">`module.exports = <span class="subst">$&#123;<span class="built_in">JSON</span>.stringify(html)&#125;</span>`</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>


<h4 id="插件机制"><a href="#插件机制" class="headerlink" title="插件机制"></a>插件机制</h4><p>通过配置webpack的plugins数组配置插件</p>
<h5 id="自动清除输出目录"><a href="#自动清除输出目录" class="headerlink" title="自动清除输出目录"></a>自动清除输出目录</h5><p>clean-webpack-plugin</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">const &#123;CleanWebpackPlugin&#125; &#x3D; require(&#39;clean-webpack-plugin&#39;);</span><br><span class="line"></span><br><span class="line">module.exports &#x3D; &#123;</span><br><span class="line">    plugins: [</span><br><span class="line">        new CleanWebpackPlugin(),</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="自动生成html-html-webpack-plugin"><a href="#自动生成html-html-webpack-plugin" class="headerlink" title="自动生成html html-webpack-plugin"></a>自动生成html html-webpack-plugin</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">const HtmlWebpakPlugin &#x3D; require(&#39;html-webpack-plugin&#39;)</span><br><span class="line"></span><br><span class="line">module.exports &#x3D; &#123;</span><br><span class="line">    plugins: [</span><br><span class="line">        new HtmlWebpakPlugin(&#123;</span><br><span class="line">            title: &#39;vue-app&#39;, </span><br><span class="line">            url: &#39;&#x2F;&#39;, &#x2F;&#x2F; 自定义参数</span><br><span class="line">            template: &#39;.&#x2F;public&#x2F;index.html&#39;, </span><br><span class="line">            filename: &#39;index.html&#39;,</span><br><span class="line">        &#125;),</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h5 id="复制文件-copy-webpack-plugin"><a href="#复制文件-copy-webpack-plugin" class="headerlink" title="复制文件  copy-webpack-plugin"></a>复制文件  copy-webpack-plugin</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">const CopyWebpackPlugin &#x3D; require(&#39;copy-webpack-plugin&#39;);</span><br><span class="line"></span><br><span class="line">module.exports &#x3D; &#123;</span><br><span class="line">    plugins: [</span><br><span class="line">        new CopyWebpackPlugin(&#123;</span><br><span class="line">            patterns: [</span><br><span class="line">                &#123;</span><br><span class="line">                    from: &#39;public&#x2F;favicon.ico&#39;,</span><br><span class="line">                    to: &#39;&#39;</span><br><span class="line">                &#125;,</span><br><span class="line">            ],</span><br><span class="line">        &#125;),</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="插件实现原理"><a href="#插件实现原理" class="headerlink" title="插件实现原理"></a>插件实现原理</h4><p>通过钩子机制实现</p>
<p>插件必须是一个函数或者包含apply 方法的对象</p>
<p>一般都会定义一个类型，通过实例来实现</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">// 实现一个去处打包后文件注释的方法</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyPlugin</span> </span>&#123;</span><br><span class="line">    <span class="comment">// apply 方法会在webpack启动时被调用</span></span><br><span class="line">    apply (compiler)&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;webpack 启动 &#x27;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="comment">// emit 钩子在webpack准备往目标目录输出文件时执行,</span></span><br><span class="line">        <span class="comment">// 第一个参数是插件名称， 第二个参数函数的参数是打包过程的上下文</span></span><br><span class="line">        compiler.hooks.emit.tap(<span class="string">&#x27;MyPlugin&#x27;</span>, <span class="function"><span class="params">compilation</span> =&gt;</span> &#123;</span><br><span class="line">            <span class="comment">// 获取即将写入的资源信息</span></span><br><span class="line">            <span class="keyword">const</span> assets = compilation.assets</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">let</span> key <span class="keyword">in</span> assets) &#123;</span><br><span class="line">                <span class="comment">// key 就是 资源文件名称</span></span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (key.endsWith(<span class="string">&#x27;.js&#x27;</span>))&#123;</span><br><span class="line">                    <span class="comment">// 这里只处理js文件</span></span><br><span class="line">                    <span class="comment">// source方法返回文件文本内容</span></span><br><span class="line">                    <span class="keyword">const</span> value = compilation.assets[key].source();</span><br><span class="line">                    <span class="comment">// 通过正则替换掉注释信息</span></span><br><span class="line">                    <span class="keyword">const</span> withoutComments = contents.replace(<span class="regexp">/\/\*\*+\*\//g</span>, <span class="string">&#x27;&#x27;</span>);</span><br><span class="line">                    compilation.assets[key] = &#123;</span><br><span class="line">                        source: <span class="function">() =&gt;</span> withoutComments,</span><br><span class="line">                        size: <span class="function">() =&gt;</span> withoutComments.length, <span class="comment">// 返回内容方法，必须</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                </span><br><span class="line">            &#125; </span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="webpack-dev-server"><a href="#webpack-dev-server" class="headerlink" title="webpack-dev-server"></a>webpack-dev-server</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">devServer: &#123;</span><br><span class="line">    historyApiFallback: true, &#x2F;&#x2F;historyApiFallback设置为true那么所有的路径都执行index.html。</span><br><span class="line">    overlay: true, &#x2F;&#x2F; 将错误显示在html之上</span><br><span class="line">    port: 8080,</span><br><span class="line">    progress: true,</span><br><span class="line">    contentBase: &#39;.&#x2F;dist&#39;,</span><br><span class="line">    open: false,</span><br><span class="line">    hot: true,</span><br><span class="line">    disableHostCheck: true,  &#x2F;&#x2F; 没有这项ie 会重复报错，</span><br><span class="line">    historyApiFallback: true,</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h4 id="热更新"><a href="#热更新" class="headerlink" title="热更新"></a>热更新</h4><h4 id="treeShaking"><a href="#treeShaking" class="headerlink" title="treeShaking"></a>treeShaking</h4><p>去除未引用代码</p>
<p>treeShaking会在生产环境下自动开启，其他环境下可以通过配置usedExports和minimize来手动开启treeShaking</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">optimization: &#123;</span><br><span class="line">    usedExports: true,</span><br><span class="line">    minimize: true,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



</section>
    <!-- Tags START -->
    
      <div class="tags">
        <span>Tags:</span>
        
  <a href="/tags#webpack" >
    <span class="tag-code">webpack</span>
  </a>

      </div>
    
    <!-- Tags END -->
    <!-- NAV START -->
    
  <div class="nav-container">
    <!-- reverse left and right to put prev and next in a more logic postition -->
    
      <a class="nav-left" href="/2020/08/27/%E8%87%AA%E5%8A%A8%E5%8C%96%E6%9E%84%E5%BB%BA/">
        <span class="nav-arrow">← </span>
        
          自动化构建
        
      </a>
    
    
      <a class="nav-right" href="/2020/08/27/%E6%A8%A1%E5%9D%97%E5%8C%96/">
        
          模块化
        
        <span class="nav-arrow"> →</span>
      </a>
    
  </div>

    <!-- NAV END -->
    <!-- 打赏 START -->
    
      <div class="money-like">
        <div class="reward-btn">
          赏
          <span class="money-code">
            <span class="alipay-code">
              <div class="code-image"></div>
              <b>使用支付宝打赏</b>
            </span>
            <span class="wechat-code">
              <div class="code-image"></div>
              <b>使用微信打赏</b>
            </span>
          </span>
        </div>
        <p class="notice">若你觉得我的文章对你有帮助，欢迎点击上方按钮对我打赏</p>
      </div>
    
    <!-- 打赏 END -->
    <!-- 二维码 START -->
    
      <div class="qrcode">
        <canvas id="share-qrcode"></canvas>
        <p class="notice">扫描二维码，分享此文章</p>
      </div>
    
    <!-- 二维码 END -->
    
      <!-- No Comment -->
    
  </article>
  <!-- Article END -->
  <!-- Catalog START -->
  
    <aside class="catalog-container">
  <div class="toc-main">
    <strong class="toc-title">Catalog</strong>
    
      <ol class="toc-nav"><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#WEBPACK"><span class="toc-nav-text">WEBPACK</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#%E6%A8%A1%E5%9D%97%E5%8C%96%E9%97%AE%E9%A2%98"><span class="toc-nav-text">模块化问题</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#%E6%89%93%E5%8C%85%E5%B7%A5%E5%85%B7"><span class="toc-nav-text">打包工具</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#%E5%AE%89%E8%A3%85"><span class="toc-nav-text">安装</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="toc-nav-text">配置文件</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#webpack-%E5%8E%9F%E7%90%86"><span class="toc-nav-text">webpack 原理</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#webpack-%E8%B5%84%E6%BA%90%E5%8A%A0%E8%BD%BD-Loader"><span class="toc-nav-text">webpack 资源加载 Loader</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-5"><a class="toc-nav-link" href="#%E5%A4%84%E7%90%86css"><span class="toc-nav-text">处理css</span></a></li><li class="toc-nav-item toc-nav-level-5"><a class="toc-nav-link" href="#%E6%96%87%E4%BB%B6%E8%B5%84%E6%BA%90%E5%8A%A0%E8%BD%BD-%E5%9B%BE%E7%89%87%E5%AD%97%E4%BD%93"><span class="toc-nav-text">文件资源加载, 图片字体</span></a></li><li class="toc-nav-item toc-nav-level-5"><a class="toc-nav-link" href="#%E7%BC%96%E8%AF%91-ES6"><span class="toc-nav-text">编译 ES6</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89-loader"><span class="toc-nav-text">自定义 loader</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#%E6%8F%92%E4%BB%B6%E6%9C%BA%E5%88%B6"><span class="toc-nav-text">插件机制</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-5"><a class="toc-nav-link" href="#%E8%87%AA%E5%8A%A8%E6%B8%85%E9%99%A4%E8%BE%93%E5%87%BA%E7%9B%AE%E5%BD%95"><span class="toc-nav-text">自动清除输出目录</span></a></li><li class="toc-nav-item toc-nav-level-5"><a class="toc-nav-link" href="#%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90html-html-webpack-plugin"><span class="toc-nav-text">自动生成html html-webpack-plugin</span></a></li><li class="toc-nav-item toc-nav-level-5"><a class="toc-nav-link" href="#%E5%A4%8D%E5%88%B6%E6%96%87%E4%BB%B6-copy-webpack-plugin"><span class="toc-nav-text">复制文件  copy-webpack-plugin</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#%E6%8F%92%E4%BB%B6%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86"><span class="toc-nav-text">插件实现原理</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#webpack-dev-server"><span class="toc-nav-text">webpack-dev-server</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#%E7%83%AD%E6%9B%B4%E6%96%B0"><span class="toc-nav-text">热更新</span></a></li><li class="toc-nav-item toc-nav-level-4"><a class="toc-nav-link" href="#treeShaking"><span class="toc-nav-text">treeShaking</span></a></li></ol></li></ol></li></ol>
    
  </div>
</aside>
  
  <!-- Catalog END -->
</main>

<script>
  (function () {
    var url = 'https://github.com/alongithub/2020/08/27/webpack/';
    var banner = ''
    if (banner !== '' && banner !== 'undefined' && banner !== 'null') {
      $('#article-banner').css({
        'background-image': 'url(' + banner + ')'
      })
    } else {
      $('#article-banner').geopattern(url)
    }
    $('.header').removeClass('fixed-header')

    // error image
    $(".markdown-content img").on('error', function() {
      $(this).attr('src', '/css/images/error_icon.png')
      $(this).css({
        'cursor': 'default'
      })
    })

    // zoom image
    $(".markdown-content img").on('click', function() {
      var src = $(this).attr('src')
      if (src !== '/css/images/error_icon.png') {
        var imageW = $(this).width()
        var imageH = $(this).height()

        var zoom = ($(window).width() * 0.95 / imageW).toFixed(2)
        zoom = zoom < 1 ? 1 : zoom
        zoom = zoom > 2 ? 2 : zoom
        var transY = (($(window).height() - imageH) / 2).toFixed(2)

        $('body').append('<div class="image-view-wrap"><div class="image-view-inner"><img src="'+ src +'" /></div></div>')
        $('.image-view-wrap').addClass('wrap-active')
        $('.image-view-wrap img').css({
          'width': `${imageW}`,
          'transform': `translate3d(0, ${transY}px, 0) scale3d(${zoom}, ${zoom}, 1)`
        })
        $('html').css('overflow', 'hidden')

        $('.image-view-wrap').on('click', function() {
          $(this).remove()
          $('html').attr('style', '')
        })
      }
    })
  })();
</script>


  <script>
    var qr = new QRious({
      element: document.getElementById('share-qrcode'),
      value: document.location.href
    });
  </script>






    <div class="scroll-top">
  <span class="arrow-icon"></span>
</div>
    <footer class="app-footer">
  <p class="copyright">
    Copyright&copy; 2019-2022 along
    <br>
    <a href="https://beian.miit.gov.cn/" target="_blank">京ICP备2020044791号-1</a>
    <!-- <br>
    Theme by <a href="https://github.com/alongithub">alongithub</a>
     -->
  </p>
</footer>

<script>
  function async(u, c) {
    var d = document, t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
    s.parentNode.insertBefore(o, s);
  }
</script>
<script>
  async("/cdn.along/fastclick/1.0.6/fastclick.min.js", function(){
    FastClick.attach(document.body);
  })
</script>

<script>
  var hasLine = 'true';
  async("/cdn.along/highlight.js/9.12.0/highlight.min.js", function(){
    $('figure pre').each(function(i, block) {
      var figure = $(this).parents('figure');
      if (hasLine === 'false') {
        figure.find('.gutter').hide();
      }
      hljs.configure({useBR: true});
      var lang = figure.attr('class').split(' ')[1] || 'code';
      var codeHtml = $(this).html();
      var codeTag = document.createElement('code');
      codeTag.className = lang;
      codeTag.innerHTML = codeHtml;
      $(this).attr('class', '').empty().html(codeTag);
      figure.attr('data-lang', lang.toUpperCase());
      hljs.highlightBlock(block);
    });
  })
</script>
<!-- Baidu Tongji -->


<script src="/js/script.js"></script>


  </body>
</html>